import scala.sys._
import scala.sys.process._
import scala.collection.mutable._
import scala.util.matching.Regex

import ui_utils._

import java.io._


object tool_emacs_assistance {
  val econf_name : String = sys.env("HOME") + "/.emacs"
  val econf_not_exists : String = "ERROR: Failed to open ~/.emacs : " + econf_name

  // option -> function 
  var opt2func : HashMap[String, Array[String] => Unit] = new HashMap() 


  // set frame dimension 
  def taskSetFrameDimension (ins : Array[String]) {
    // check ins 
    assert(ins.length == 1, {println("ERROR [taskSetFrameDimension]: Invalid parameter: " + ins.toString)})

    // get an integer 
    var dims = UI_UTILS.GetIntsFromConsole(ins(0) + ": ")
    assert(dims.length == 1, {println("Error [taskSetFrameDimension]: Only one integer is required")})

    // write ~/.emacs 
    try {
      // open ~/.emacs file
      var efile = new FileWriter(econf_name, true)

      // write comment and command
      efile.write("; -- frame " + ins(0) + " -- \n")
      efile.write("(add-to-list 'default-frame-alist '(" + ins(0) + " . " + dims(0).toString + ")) \n")
      efile.write("\n")

      // close ~/.emacs file
      efile.flush()
      efile.close()
    } catch {
      case ex: Exception => println(ex) ; assert(false, {println(econf_not_exists)})
    }
  }
  def taskSetFrameWidth (ins : Array[String]) {
    taskSetFrameDimension((new Array[String](0)) :+ "width")
  }
  def taskSetFrameHeight (ins : Array[String]) {
    taskSetFrameDimension((new Array[String](0)) :+ "height")
  }


  // install CUDA syntax 
  def taskAddCUDASyntax (ins : Array[String]) {
    try {
      // open ~/.emacs file
      var efile = new FileWriter(econf_name, true)

      // write comment and command
      efile.write("; -- cuda syntax -- \n")
      efile.write("(add-to-list 'auto-mode-alist' (\"\\.cu$\" . c++-mode)) \n")
      efile.write("\n")

      // close ~/.emacs file
      efile.flush()
      efile.close()
    } catch {
      case ex: Exception => println(ex) ; assert(false, {println(econf_not_exists)})
    }
  }

  
  def RunTask (tlist : HashMap[String, Array[String] => Unit], op : String, par : Array[String]) {
    if (tlist.keys.exists(_ == op)) {
      tlist(op)(par)
    }
    else {
      assert(false, {println("ERROR: Unknown option: " + op)})
    }
  }


  def main (argv : Array[String]) {
    // check argv 
    assert(argv.length == 1, {println("Usage: tool_emacs_assistance option")})
    var op = argv(0)

    // create opt2func
    opt2func += ("add-cuda-syntax" -> taskAddCUDASyntax)
    opt2func += ("set-frame-width" -> taskSetFrameWidth)
    opt2func += ("set-frame-height" -> taskSetFrameHeight)

    // run 
    RunTask(opt2func, op, argv)
  }
}
